Repository navigation
Conversation
…unched sessions MCP-launched agent sessions ran the hardcoded builtin command (e.g. `claude --dangerously-skip-permissions`) instead of the user's UI-configured launch command. Agent preset overrides live only in the device SQLite settings, so the cloud MCP server can't read them and bakes the command from builtins alone. Resolve the effective command on the device, where the presets exist. The MCP server keeps sending the baked builtin command as a fallback and now also carries what the device needs to re-resolve: the raw `prompt` for prompt launches, and `taskPromptContent`/`taskPromptFileName` for task launches. A new device re-resolves from the user's presets via the existing `resolveAgentConfigs` path; it falls back to the baked command whenever the presets, a matching enabled terminal config, or the prompt fields are absent. The change is additive over the server->device agent_commands queue, so it is safe across rolling updates: old devices ignore the new fields and run the baked command, and new devices tolerate old-server requests that lack them. Out of scope: the cwd/worktree-readiness spawn race in create_workspace (worktree dir may not exist when a PTY spawns immediately after). Different code path; separate follow-up.
📝 WalkthroughWalkthroughTerminal launch requests now preserve prompt and task-file metadata. Desktop command execution uses resolved device-local agent presets to rebuild eligible terminal commands while retaining baked-command fallbacks and leaving chat launches unchanged. ChangesAgent command resolution
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MCPStartAgentSession
participant SharedLaunchSchema
participant useCommandWatcher
participant startAgentSession
participant AgentSessionOrchestrator
MCPStartAgentSession->>SharedLaunchSchema: build terminal request with prompt or task-file metadata
SharedLaunchSchema->>useCommandWatcher: normalized launch request
useCommandWatcher->>startAgentSession: execute with resolved agent-config lookup
startAgentSession->>AgentSessionOrchestrator: launch rebuilt local command or baked fallback
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR fixes a mismatch between desktop UI agent launching and MCP-launched agent sessions by ensuring device-local agent preset overrides (stored in SQLite) are honored when sessions are initiated via MCP. It does this by having the device re-resolve the effective terminal command from its local presets, while keeping the server-provided baked command as a safe fallback for rolling upgrades.
Changes:
- Extended the shared terminal launch schema to optionally carry the raw
prompt(in addition to the bakedcommand) so the device can re-resolve using local presets. - Updated MCP start-agent-session request building to include prompt/task prompt fields needed for device-side re-resolution (task launches now follow the same “file command + prompt content/filename” shape as the UI).
- Updated the desktop command-watcher tool context and start-agent-session tool to re-resolve terminal commands via
resolveAgentConfigswhen local presets are available, with comprehensive fallback behavior covered by tests.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/agent-launch.ts | Adds optional terminal.prompt to support device-side command re-resolution. |
| packages/shared/src/agent-launch.test.ts | Adds schema round-trip test coverage for the new terminal.prompt field. |
| packages/mcp/src/tools/devices/start-agent-session/start-agent-session.test.ts | Updates MCP tests to assert task prompt fields/file command shape and prompt-carrying behavior. |
| packages/mcp/src/tools/devices/start-agent-session/shared.ts | Switches MCP task launches to file-command shape and includes prompt/task prompt fields for device re-resolution. |
| apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/useCommandWatcher.ts | Wires settings.getAgentPresets into a memoized indexed map exposed via tool context. |
| apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/types.ts | Extends ToolContext with optional getResolvedAgentConfigsById for backwards compatibility. |
| apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-agent-session.ts | Implements device-local command re-resolution for terminal launches, preserving server-authoritative fields and falling back safely. |
| apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-agent-session.test.ts | Adds device-side tests validating override behavior and all intended fallback cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a9e60a265
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/mcp/src/tools/devices/start-agent-session/shared.ts (1)
139-183: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftDuplicate
buildTaskLaunchRequestimplementation across packages.This function mirrors
buildTaskLaunchRequestinpackages/shared/src/agent-launch.ts(lines 205-257): both computetaskPromptFileName, callbuildAgentFileCommand/buildAgentTaskPrompt, and populate the sameterminal.{name,taskPromptContent,taskPromptFileName}triplet. This PR had to touch both to add the file-based approach and prompt metadata — a sign the duplication will keep requiring synchronized edits (and risks drifting silently if one is missed).Consider extracting the shared terminal-request-building logic into
@superset/shared(parameterized overTaskInput/TaskRecord) so both callers converge on one implementation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/devices/start-agent-session/shared.ts` around lines 139 - 183, The terminal launch construction in buildTaskLaunchRequest is duplicated with the implementation in the shared agent-launch module. Extract the common terminal-request-building logic into `@superset/shared`, parameterized to accept the relevant TaskInput/TaskRecord shape, and update both callers to reuse it while preserving the existing superset chat branch and request fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/mcp/src/tools/devices/start-agent-session/shared.ts`:
- Around line 139-183: The terminal launch construction in
buildTaskLaunchRequest is duplicated with the implementation in the shared
agent-launch module. Extract the common terminal-request-building logic into
`@superset/shared`, parameterized to accept the relevant TaskInput/TaskRecord
shape, and update both callers to reuse it while preserving the existing
superset chat branch and request fields.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 219182b2-d43b-4b9c-bbeb-b5ecfd24ee04
📒 Files selected for processing (8)
apps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-agent-session.test.tsapps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/start-agent-session.tsapps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/tools/types.tsapps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/useCommandWatcher/useCommandWatcher.tspackages/mcp/src/tools/devices/start-agent-session/shared.tspackages/mcp/src/tools/devices/start-agent-session/start-agent-session.test.tspackages/shared/src/agent-launch.test.tspackages/shared/src/agent-launch.ts
The command-watcher's pendingCommands query can emit before settings.getAgentPresets resolves. In that window the resolved-config index was an empty map, so resolveDeviceLocalCommand found no config, fell back to the server-baked command, and the watcher marked the command handled — the launch was never re-resolved once the overrides arrived, intermittently ignoring device-local agent command overrides on startup. Gate shouldWatch on the presets query having settled, and return undefined (not an empty index) while it is still loading so the loading state is never mistaken for "no override".
|
Re: CodeRabbit nitpick on duplicate |
Problem
In Superset, a user can customize each agent's launch command in the desktop UI (e.g. set
claudetoclaude --permission-mode plan --dangerously-skip-permissions). The desktop UI honors these overrides, but MCP-launched sessions ignore them — an agent started viastart_agent_session/start_agent_session_with_promptalways ran the hardcoded builtin command, so the user's plan-mode / custom flags never took effect.Root cause: user overrides (
agentPresetOverrides,agentCustomDefinitions) are stored device-local in SQLite (packages/local-dbsettings). They are not in Postgres, so the cloud MCP server can't read them and bakes the command from builtins only. The device command-watcher trusts that baked command verbatim, even though the device has the presets viasettings.getAgentPresets.Approach — device re-resolves; additive & rolling-update-safe
Overrides only exist on the device, so the effective command can only be resolved there. The change is additive over the server→device
agent_commandsqueue so it stays compatible across rolling updates:prompt(prompt launches) andtaskPromptContent/taskPromptFileName(task launches, matching how UI task launches already behave).resolveAgentConfigspath; it falls back to the baked command when the presets, a matching enabled terminal config, or the prompt fields are absent.Only the command string is overwritten — server-provided
name/paneId/files/taskPromptContentstay authoritative. Chat/superset launches are never touched.Changes
packages/shared/src/agent-launch.ts— add optionalprompttoterminalLaunchConfigSchema.packages/mcp/.../start-agent-session/shared.ts— prompt launch carriesprompt; task launch switched to the UI file-command shape (buildAgentFileCommand+taskPromptContent+taskPromptFileName)..../useCommandWatcher/tools/types.ts— add optionalgetResolvedAgentConfigsByIdgetter toToolContext..../useCommandWatcher/useCommandWatcher.ts— wiresettings.getAgentPresets→ memoizedindexResolvedAgentConfigs→ thetoolContextgetter..../useCommandWatcher/tools/start-agent-session.ts—resolveDeviceLocalCommandre-resolves the terminal command from local presets (task → file command, prompt → prompt command), falling back to the baked command in every gap.Tests
tools/start-agent-session.test.ts): override prompt/task launches use the overridden command; authoritative fields preserved; baked-command fallback for disabled config, missing config, absent resolver getter, and old-server requests; chat/superset untouched.terminal.prompt; task request uses file command + prompt content/filename.prompt.tsc --noEmit, shared/mcp typechecks, and biome all clean.Out of scope (separate follow-up)
The cwd/worktree-readiness spawn race —
create_workspacereturns before the worktree dir exists (initializeWorkspaceWorktreeis fire-and-forget), so a PTY spawned immediately after can die. It's a different code path (main-process init vs renderer command resolution) and should ship as its own change.Summary by cubic
MCP-launched agent sessions now honor device-local agent preset overrides from the desktop UI. Commands are resolved on the device using local presets with baked fallbacks, and MCP command processing is deferred until presets load to avoid a startup race that could ignore overrides.
terminal.promptortaskPromptContent/taskPromptFileName; the device prefers local re-resolution and falls back when data or presets are missing (rolling-update safe).prompttoterminalLaunchConfigSchemain@superset/sharedto carry raw prompts for device-side resolution.getResolvedAgentConfigsById; onlyterminal.commandis replaced, whilename/paneId/files remain authoritative. Chat/superset launches are untouched.Written for commit 4ffddd2. Summary will update on new commits.
Summary by CodeRabbit
New Features
Tests